#pragma once
#include <memory>
#include "tinyrpc/base/coroutine/coroutine.h"
#include "tinyrpc/net/channel/socketchannel.h"
#include "tinyrpc/base/timestamp.h"

namespace TinyRPC{

// RPCService 的状态信息
enum RPCServiceStatus{
    RPCServiceINIT,                //刚初始化
    CONNECTED,
    DISCONNECTED,
    DEAD
};

class RPCService{
public:
    RPCService(INetAddress address)
    :m_serverAddress(address){
        m_sockChannel.reset();
        m_status = RPCServiceINIT;
    }

    void setStatus(RPCServiceStatus status){
        m_status = status;
    }
    RPCServiceStatus getStatus(){
        return m_status;
    }

    int connect(){
        
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        m_sockChannel = std::make_shared<SocketChannel>(sockfd, m_serverAddress);
        int ret = m_sockChannel->connect(m_serverAddress);
        if(ret < 0){
            m_status =DEAD;
            return -1;
        }
        m_status = CONNECTED;
        return ret;
    }

    SocketChannelPtr getSockSocketChannel(){
        return m_sockChannel;
    }

    void closeConn(){
        m_status = DISCONNECTED;
        m_sockChannel->close();
        m_sockChannel.reset();
        m_receiveResponseCoroutine = nullptr;
    }

    void setCoroutinePtr(CoroutinePtr co){
        m_receiveResponseCoroutine = co;
    }

    CoroutinePtr getCoroutinePtr(){
        return m_receiveResponseCoroutine;
    }
    void clearCoroutinePtr(){
        m_receiveResponseCoroutine.reset();
    }

private:
    RPCServiceStatus m_status;
    INetAddress m_serverAddress;
    SocketChannelPtr m_sockChannel;
    CoroutinePtr m_receiveResponseCoroutine;
};

using RPCServicePtr = std::shared_ptr<RPCService>;
}